/**
 * @addtogroup mfc_mem_codec
 * mfc_mem_codec
 * @{
 */
/**
 * @file         mfc_mem_codec.h
 * @brief        内存编解码对象
 * @note         所有接口内部不判断对象参数的有效性，需要外部自己判断
 * @author       尤胜坤[Akee](ysk@hopechart.com)
 * @date         2019-11-4
 * @version      1.0
 *
 * @par          修改日志
 * <table>
 * <tr><th>Date        <th>Version               <th>Author          <th>Description
 * <tr><td>2019-11-4   <td>1.0                   <td>Akee            <td>创建初始版本
 * @copyright    杭州鸿泉物联网技术股份有限公司
 */
#ifndef _MFC_MEM_CODEC_H_
#define _MFC_MEM_CODEC_H_

#include "ofc_types.h"
#include "ofc_object.h"
#include "mfc_string.h"

#ifdef __cplusplus
extern "C" {
#endif

/**
 * 缓冲编解码对象
 */
struct TMfMemCodecTag 
{
    TOfObject parent_;      ///< 基类

PROTECTED
    TOfVirtualMethod Destroy_;  ///< 析构事件
    
PRIVATE
    Byte *buf_;             ///< 数据内存
    Int32 size_;            ///< 数据大小
    Int32 position_;        ///< 当前位置
};
typedef struct TMfMemCodecTag TMfMemCodec;

/**
 * 构造函数
 * @param self: 对象指针
 * @param buf: 缓冲编码器的内存数据
 * @param size: 缓冲编码器的内存大小
 * @return 
 */
void TMfMemCodecCreate(TMfMemCodec *self, Byte *buf, Int32 size);

/**
 * 获取1个字节,内部判断参数有效性
 * @param self: 对象指针
 * @param value: 获取的值地址
 * @return 获取是否成功
 */
Bool TMfMemCodecGetByte(TMfMemCodec *self, Byte *value);

/**
 * 获取n个字节
 * @param self: 对象指针
 * @param value: 获取的值地址
 * @param count: 获取个数
 * @return 实际获取的个数
 */
Int32 TMfMemCodecGetBytes(TMfMemCodec *self, Byte *value, Int32 count);

/**
* 获取n个字节
* @param self: 对象指针
* @param value: 存放获取的数据内容对象
* @param count: 获取个数,<=0: 获取剩余所有数据; >0: 获取规定的数据大小
* @return 实际获取的个数
*/
Int32 TMfMemCodecGetStrings(TMfMemCodec *self, TMfString *value, Int32 count);

/**
 * 获取2个字节,内部判断参数有效性
 * @param self: 对象指针
 * @param value: 获取的值地址
 * @param conv_byte_order: 是否转换字节序
 * @return 获取是否成功
 */
Bool TMfMemCodecGetWord(TMfMemCodec *self, Word *value, Bool conv_byte_order);

/**
 * 获取n个字节
 * @param self: 对象指针
 * @param value: 获取的值地址
 * @param count: 获取个数
 * @param conv_byte_order: 是否转换字节序
 * @return 实际获取的个数
 */
Int32 TMfMemCodecGetWords(TMfMemCodec *self, Word *value, Int32 count, Bool conv_byte_order);

/**
 * 获取4个字节,内部判断参数有效性
 * @param self: 对象指针
 * @param value: 获取的值地址
 * @param conv_byte_order: 是否转换字节序
 * @return 获取是否成功
 */
Bool TMfMemCodecGetDWord(TMfMemCodec *self, DWord *value, Bool conv_byte_order);

/**
 * 获取n个字节
 * @param self: 对象指针
 * @param value: 获取的值地址
 * @param count: 获取个数
 * @param conv_byte_order: 是否转换字节序
 * @return 实际获取的个数
 */
Int32 TMfMemCodecGetDWords(TMfMemCodec *self, DWord *value, Int32 count, Bool conv_byte_order);

/**
 * 获取8个字节,内部判断参数有效性
 * @param self: 对象指针
 * @param value: 获取的值地址
 * @param conv_byte_order: 是否转换字节序
 * @return 获取是否成功
 */
Bool TMfMemCodecGetQWord(TMfMemCodec *self, QWord *value, Bool conv_byte_order);

/**
 * 获取n个字节
 * @param self: 对象指针
 * @param value: 获取的值地址
 * @param count: 获取个数
 * @param conv_byte_order: 是否转换字节序
 * @return 实际获取的个数
 */
Int32 TMfMemCodecGetQWords(TMfMemCodec *self, QWord *value, Int32 count, Bool conv_byte_order);

/**
 * 设置1个字节的数据,内部判断参数有效性
 * @param self: 对象指针
 * @param value: 数据内容
 * @return 设置是否成功
 */
Bool TMfMemCodecSetByte(TMfMemCodec *self, Byte value);

/**
 * 设置n个字节
 * @param self: 对象指针
 * @param value: 设置的值地址
 * @param count: 设置个数
 * @return 实际设置的个数
 */
Int32 TMfMemCodecSetBytes(TMfMemCodec *self, Byte *value, Int32 count);

/**
* 设置n个字节
* @param self: 对象指针
* @param value: 字符串对象
* @param count: 设置个数,<=0: 设置长度为value对象的长度, >0: 字符串value长度与count较小的数据
* @return 实际设置的个数
*/
Int32 TMfMemCodecSetStrings(TMfMemCodec *self, TMfString *value, Int32 count);

/**
 * 设置2个字节的数据,内部判断参数有效性
 * @param self: 对象指针
 * @param value: 数据内容
 * @param conv_byte_order: 是否转换字节序
 * @return 设置是否成功
 */
Bool TMfMemCodecSetWord(TMfMemCodec *self, Word value, Bool conv_byte_order);

/**
 * 设置n*count个字节
 * @param self: 对象指针
 * @param value: 设置的值地址
 * @param count: 设置个数
 * @param conv_byte_order: 是否转换字节序
 * @return 实际设置的个数
 */
Int32 TMfMemCodecSetWords(TMfMemCodec *self, Word *value, Int32 count, Bool conv_byte_order);

/**
 * 设置4个字节的数据,内部判断参数有效性
 * @param self: 对象指针
 * @param value: 数据内容
 * @param conv_byte_order: 是否转换字节序
 * @return 设置是否成功
 */
Bool TMfMemCodecSetDWord(TMfMemCodec *self, DWord value, Bool conv_byte_order);

/**
 * 设置n*count个字节
 * @param self: 对象指针
 * @param value: 设置的值地址
 * @param count: 设置个数
 * @param conv_byte_order: 是否转换字节序
 * @return 实际设置的个数
 */
Int32 TMfMemCodecSetDWords(TMfMemCodec *self, DWord *value, Int32 count, Bool conv_byte_order);

/**
 * 设置8个字节的数据,内部判断参数有效性
 * @param self: 对象指针
 * @param value: 数据内容
 * @param conv_byte_order: 是否转换字节序
 * @return 设置是否成功
 */
Bool TMfMemCodecSetQWord(TMfMemCodec *self, QWord value, Bool conv_byte_order);

/**
 * 设置n*count个字节
 * @param self: 对象指针
 * @param value: 设置的值地址
 * @param count: 设置个数
 * @param conv_byte_order: 是否转换字节序
 * @return 实际设置的个数
 */
Int32 TMfMemCodecSetQWords(TMfMemCodec *self, QWord *value, Int32 count, Bool conv_byte_order);

/**
 * 复位内部的提取位置
 * @param self: 对象指针
 * @return
 */
void TMfMemCodecResetPos(TMfMemCodec *self);

/**
 * 设置缓冲编码器的内存数据,自动复位pos
 * @param self: 对象指针
 * @param buf:  内存数据,为了提高效率，调用者需要注意是否有设置为NULL,内部不做判断
 * @param buf_size: 内存大小
 * @return 
 */
void TMfMemCodecSetCodecMem(TMfMemCodec *self, Byte *buf, Int32 buf_size);

/**
 * 返回当前缓冲编码器的位置
 * @param self: 对象指针
 * @return 当前编码位置
 */
Int32 TMfMemCodecPosition(TMfMemCodec *self);

/**
 * 设置内部位置
 * @param self: 对象指针
 * @param value: 位置
 * @return 设置是否成功
 */
Bool TMfMemCodecSetPosition(TMfMemCodec *self, Int32 value);

/**
 * 获取缓冲编码器的大小
 * @param self: 对象指针
 * @return
 */
Int32 TMfMemCodecSize(TMfMemCodec *self);

/**
 * 获取缓冲编码器的内存
 * @param self: 对象指针
 * @return 内存
 */
Byte *TMfMemCodecBuf(TMfMemCodec *self);

/**
 * 获取当前位置的指针
 * @param self: 对象指针
 * @return 指针
 */
Byte *TMfMemCodecGetPointer(TMfMemCodec *self);

/**
 * 按字节偏移内部位置
 * @param self: 对象指针
 * @param size: 偏移大小，支持正负
 * @return 偏移是否成功
 */
Bool TMfMemCodecSkipBytes(TMfMemCodec *self, Int32 size);

/**
 * 获取缓冲编码器的剩余数据大小
 * @param self: 对象指针
 * @return 剩余数据大小
 */
Int32 TMfMemCodecRemainSize(TMfMemCodec *self);

#ifdef __cplusplus
}
#endif
#endif// _OC_BUF_CODEC_H_

/**
 * @}
 */
